package com.icesoft.generation.service.impl;

import com.icesoft.framework.core.service.impl.BaseServiceImpl;
import com.icesoft.generation.config.VelocityInitializer;
import com.icesoft.generation.entity.GenTable;
import com.icesoft.generation.helper.VelocityHelper;
import com.icesoft.generation.mapper.GenTableMapper;
import com.icesoft.generation.service.GenTableService;
import com.icesoft.generation.vo.GenTableVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.CharEncoding;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static cn.hutool.core.util.CharsetUtil.UTF_8;

@Slf4j
@Service
public class GenTableServiceImpl extends BaseServiceImpl<GenTableMapper, GenTable> implements GenTableService {

	public byte[] getZip(Long id) {
		GenTableVO table = getViewObject(id, GenTableVO.class);
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);
		VelocityInitializer.initVelocity();
		VelocityContext context = VelocityHelper.prepareContext(table);
		// 获取模板列表
		List<String> templates = VelocityHelper.getTemplateList();
		for (String template : templates) {
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, UTF_8);
			tpl.merge(context, sw);
			try {
				String fileName = VelocityHelper.getFileName(template, table);
				int src = fileName.indexOf("src");
				// 添加到zip
				zip.putNextEntry(new ZipEntry(fileName.substring(src)));
				IOUtils.write(sw.toString(), zip, UTF_8);
				IOUtils.closeQuietly(sw);
				zip.flush();
				zip.closeEntry();
			} catch (IOException e) {
				log.error("渲染模板失败，表名：" + table.getTableName(), e);
			}
		}
		IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}

	public byte[] getVueZip(Long id) {
		GenTableVO table = getViewObject(id, GenTableVO.class);
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);
		VelocityInitializer.initVelocity();
		VelocityContext context = VelocityHelper.prepareContext(table);
		// 获取模板列表
		List<String> templates = VelocityHelper.getVueTemplateList();
		for (String template : templates) {
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, UTF_8);
			tpl.merge(context, sw);
			try {
				String vueFileName = VelocityHelper.getVueFileName(template, table);
				int src = vueFileName.indexOf("src");
				// 添加到zip
				zip.putNextEntry(new ZipEntry(vueFileName.substring(src)));
				IOUtils.write(sw.toString(), zip, UTF_8);
				IOUtils.closeQuietly(sw);
				zip.flush();
				zip.closeEntry();
			} catch (IOException e) {
				log.error("渲染模板失败，表名：" + table.getTableName(), e);
			}
		}
		IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}


	public Map<String, String> preview(Long id) {
		GenTableVO genTable = getViewObject(id, GenTableVO.class);
		Map<String, String> dataMap = new LinkedHashMap<>();
		VelocityInitializer.initVelocity();
		VelocityContext context = VelocityHelper.prepareContext(genTable);
		// 获取模板列表
		List<String> templates = VelocityHelper.getAllTemplateList();
		for (String template : templates) {
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, UTF_8);
			tpl.merge(context, sw);
			dataMap.put(template, sw.toString());
		}
		return dataMap;
	}

	public void generatorCode(Long id) throws IOException {
		GenTableVO table = getViewObject(id, GenTableVO.class);
		VelocityInitializer.initVelocity();
		VelocityContext context = VelocityHelper.prepareContext(table);
		// 获取模板列表
		List<String> templates = VelocityHelper.getTemplateList();
		for (String template : templates) {

			String fileName = VelocityHelper.getFileName(template, table);
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, CharEncoding.UTF_8);
			tpl.merge(context, sw);

			try {
				new File(fileName).getParentFile().mkdirs();
				FileOutputStream fos = new FileOutputStream(fileName, false);  // true 附加模式
				fos.write(sw.toString().getBytes());
				fos.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	public void generatorVueCode(Long id) throws IOException {
		GenTableVO table = getViewObject(id, GenTableVO.class);
		VelocityInitializer.initVelocity();
		VelocityContext context = VelocityHelper.prepareContext(table);
		// 获取模板列表
		List<String> templates = VelocityHelper.getVueTemplateList();
		for (String template : templates) {

			String fileName = VelocityHelper.getVueFileName(template, table);
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, CharEncoding.UTF_8);
			tpl.merge(context, sw);

			try {
				new File(fileName).getParentFile().mkdirs();
				FileOutputStream fos = new FileOutputStream(fileName, false);  // true 附加模式
				fos.write(sw.toString().getBytes());
				fos.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

}
